/*
 * ElseBlockInstruction.cpp
 *
 *  Created on: 30/dic/2010
 *      Author: computer
 */

#include "ElseBlockInstruction.h"
#include "Null.h"
#include <sstream>

namespace TreeExpression {

ElseBlockInstruction::ElseBlockInstruction() : FlowExpression(), Expression_CRTP<ElseBlockInstruction>(), stop(false) { }

ElseBlockInstruction::ElseBlockInstruction(const ElseBlockInstruction& copy) : Expression(copy), FlowExpression(copy), Expression_CRTP<ElseBlockInstruction>(copy), stop(copy.stop), endElseBlock(copy.endElseBlock), listElseBlock(copy.listElseBlock) { }

ElseBlockInstruction::~ElseBlockInstruction() { }

AutoPointer<Expression> ElseBlockInstruction::eval(CopyPointer<Context>& context) {
	std::list< AutoPointer<Expression> >::iterator i;
	for (i = listElseBlock.begin(); i != listElseBlock.end(); ++i) {
		IfInstruction* ifInstruction = dynamic_cast<IfInstruction*>(i->get());//TODO warning sf
		AutoPointer<Expression> tmp = ifInstruction->eval(context);
		if (ifInstruction->isExecuted()) {
			if (ifInstruction->isStop()) {
				stop = true;
				return tmp;
			}
			else return AutoPointer<TreeExpression::Expression>(new TreeExpression::Null());
		}
	}
	if (!endElseBlock.isNull()) {
		IfInstruction* ifInstruction = dynamic_cast<IfInstruction*>(endElseBlock.get());//TODO warning sf
		AutoPointer<Expression> tmp = ifInstruction->eval(context);
		if (ifInstruction->isExecuted()) {
			if (ifInstruction->isStop()) {
				stop = true;
				return tmp;
			}
			else return AutoPointer<TreeExpression::Expression>(new TreeExpression::Null());
		}
	}
	return AutoPointer<TreeExpression::Expression>(new TreeExpression::Null());
}

std::string ElseBlockInstruction::toString() const {
	std::ostringstream oss;
	//oss << "if (" << condition->toString() << ") ";
	//TODO
	return oss.str();
}

Expression* ElseBlockInstruction::clone() const {
	ElseBlockInstruction* ris = new ElseBlockInstruction();
	std::list< AutoPointer<Expression> >::const_iterator i;
	for (i = listElseBlock.begin(); i != listElseBlock.end(); ++i) {
		ris->addElseBlock(AutoPointer<Expression>((*i)->cloneTree()));
	}
	ris->stop = stop;
	ris->setEndElseBlock(AutoPointer<Expression>(this->endElseBlock->cloneTree()));
	return ris;
}

void ElseBlockInstruction::addElseBlock(const AutoPointer<Expression>& toAdd) {
	listElseBlock.push_back(toAdd);
}

void ElseBlockInstruction::setEndElseBlock(const AutoPointer<Expression>& toSet) {
	endElseBlock = toSet;
}

bool ElseBlockInstruction::isStop() const {
	return stop;
}

}
